package com.synergy.stockflow.utils;

/**
 * 雪花算法生成唯一ID
 * 支持分布式部署
 */
public class IdUtils {

    // Twitter Snowflake 算法实现简化版

    private final long nodeId;
    private long lastTimestamp = -1L;
    private long nodeIdBits = 10L;
    private long sequenceBits = 12L;
    private long maxSequence = ~(-1L << sequenceBits);

    private long nodeIdShift = sequenceBits;
    private long timestampLeftShift = sequenceBits + nodeIdBits;
    private long sequenceMask = ~(-1L << sequenceBits);

    private long sequence = 0L;

    public IdUtils(long nodeId) {
        if (nodeId > ((1 << nodeIdBits) - 1)) {
            throw new IllegalArgumentException("节点ID超出范围");
        }
        this.nodeId = nodeId << sequenceBits;
    }

    public synchronized long nextId() {
        long timestamp = System.currentTimeMillis();

        if (timestamp < lastTimestamp) {
            throw new RuntimeException("时钟回拨");
        }

        if (timestamp == lastTimestamp) {
            sequence = (sequence + 1) & sequenceMask;
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0;
        }

        lastTimestamp = timestamp;

        return (timestamp << timestampLeftShift)
                | nodeId
                | sequence;
    }

    private long tilNextMillis(long lastTimestamp) {
        long timestamp = System.currentTimeMillis();
        while (timestamp <= lastTimestamp) {
            timestamp = System.currentTimeMillis();
        }
        return timestamp;
    }

    /**
     * 示例：创建一个 ID 生成器
     */
    private static final IdUtils idWorker = new IdUtils(1);

    public static long randomId() {
        return idWorker.nextId();
    }
}
